package com.edu.exam.entity.grading.audit;

import com.edu.exam.enums.grading.ActionType;
import com.edu.exam.enums.grading.ActionStatus;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

/**
 * 成绩审核动作实体类
 * [所属模块] G-02 成绩审核模块
 * 对应数据库表：grade_audit_action
 *
 * <p>成绩审核动作实体用于管理审核节点中的具体审核动作，包含
 * 动作配置信息、执行参数、状态管理、结果处理等。支持复杂的审核动作定义和执行控制。</p>
 *
 *
 * <p>核心功能：
 * - 动作配置：管理动作的基本配置和属性
 * - 执行控制：管理动作的执行过程和状态
 * - 参数管理：管理动作的输入参数和输出结果
 * - 状态管理：管理动作的执行状态和生命周期
 * - 结果处理：处理动作的执行结果和后续操作</p>
 *
 * @author 系统生成
 * @version 1.0
 * @since 2025-11-10
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class GradeAuditAction {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 节点ID
     *
     * <p>所属节点的ID。</p>
     */
    @Column(name = "node_id", nullable = false, length = 50)
    private String nodeId;

    /**
     * 动作ID
     *
     * <p>动作的唯一标识符。</p>
     */
    @Column(name = "action_id", nullable = false, length = 50, unique = true)
    private String actionId;

    /**
     * 动作名称
     *
     * <p>动作的显示名称。</p>
     */
    @Column(name = "action_name", nullable = false, length = 200)
    private String actionName;

    /**
     * 动作类型
     *
     * <p>动作的类型。
     * 支持的类型：APPROVE（通过）、REJECT（拒绝）、RETURN（退回）、FORWARD（转发）、CONSULT（咨询）、NOTIFY（通知）、REVIEW（复核）、ESCALATE（上报）、CUSTOM（自定义）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "action_type", nullable = false, length = 20)
    private ActionType actionType = ActionType.APPROVE;

    /**
     * 动作描述
     *
     * <p>动作的详细描述。</p>
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;

    /**
     * 目标状态
     *
     * <p>执行动作后要转换到的目标状态。</p>
     */
    @Column(name = "target_status", length = 50)
    private String targetStatus;

    /**
     * 执行条件
     *
     * <p>动作的执行条件，JSON格式存储。</p>
     */
    @Column(name = "execution_conditions", columnDefinition = "TEXT")
    private String executionConditions;

    /**
     * 输入参数
     *
     * <p>动作执行所需的输入参数，JSON格式存储。</p>
     */
    @Column(name = "input_parameters", columnDefinition = "TEXT")
    private String inputParameters;

    /**
     * 输出结果
     *
     * <p>动作执行后的输出结果，JSON格式存储。</p>
     */
    @Column(name = "output_result", columnDefinition = "TEXT")
    private String outputResult;

    /**
     * 执行者ID
     *
     * <p>执行动作的用户ID。</p>
     */
    @Column(name = "executor_id", length = 50)
    private String executorId;

    /**
     * 执行者姓名
     *
     * <p>执行动作的用户姓名。</p>
     */
    @Column(name = "executor_name", length = 100)
    private String executorName;

    /**
     * 动作状态
     *
     * <p>动作的执行状态。</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "status", nullable = false, length = 20)
    private ActionStatus status = ActionStatus.PENDING;

    /**
     * 执行时间
     *
     * <p>动作的执行时间。</p>
     */
    @Column(name = "execution_time")
    private LocalDateTime executionTime;

    /**
     * 完成时间
     *
     * <p>动作的完成时间。</p>
     */
    @Column(name = "completion_time")
    private LocalDateTime completionTime;

    /**
     * 执行耗时（毫秒）
     *
     * <p>动作执行的耗时时间。</p>
     */
    @Column(name = "execution_duration")
    private Long executionDuration;

    /**
     * 是否必需
     *
     * <p>动作是否为必需执行动作。</p>
     */
    @Column(name = "is_required", nullable = false)
    private Boolean isRequired = true;

    /**
     * 是否可执行
     *
     * <p>动作是否可以执行。</p>
     */
    @Column(name = "is_executable", nullable = false)
    private Boolean isExecutable = true;

    /**
     * 是否已执行
     *
     * <p>动作是否已经执行。</p>
     */
    @Column(name = "is_executed", nullable = false)
    private Boolean isExecuted = false;

    /**
     * 执行顺序
     *
     * <p>动作在节点中的执行顺序。</p>
     */
    @Column(name = "execution_order", nullable = false)
    private Integer executionOrder = 0;

    /**
     * 权限要求
     *
     * <p>执行动作所需的权限，JSON格式存储。</p>
     */
    @Column(name = "permission_requirements", columnDefinition = "TEXT")
    private String permissionRequirements;

    /**
     * 执行脚本
     *
     * <p>动作的执行脚本或业务逻辑。</p>
     */
    @Column(name = "execution_script", columnDefinition = "TEXT")
    private String executionScript;

    /**
     * 回调函数
     *
     * <p>动作执行完成后的回调函数。</p>
     */
    @Column(name = "callback_function", length = 200)
    private String callbackFunction;

    /**
     * 错误信息
     *
     * <p>动作执行过程中的错误信息。</p>
     */
    @Column(name = "error_message", columnDefinition = "TEXT")
    private String errorMessage;

    /**
     * 重试次数
     *
     * <p>动作的重试执行次数。</p>
     */
    @Column(name = "retry_count", nullable = false)
    private Integer retryCount = 0;

    /**
     * 最大重试次数
     *
     * <p>动作允许的最大重试次数。</p>
     */
    @Column(name = "max_retry_count", nullable = false)
    private Integer maxRetryCount = 3;

    /**
     * 超时时间（秒）
     *
     * <p>动作的执行超时时间。</p>
     */
    @Column(name = "timeout_seconds")
    private Integer timeoutSeconds;

    /**
     * 执行环境
     *
     * <p>动作的执行环境配置，JSON格式存储。</p>
     */
    @Column(name = "execution_environment", columnDefinition = "TEXT")
    private String executionEnvironment;

    /**
     * 动作标签
     *
     * <p>JSON格式的动作标签，用于分类和过滤。</p>
     */
    @Column(name = "action_tags", columnDefinition = "TEXT")
    private String actionTags;

    /**
     * 动作备注
     *
     * <p>动作的备注信息。</p>
     */
    @Column(name = "action_notes", columnDefinition = "TEXT")
    private String actionNotes;

    // ===== 关联关系 =====

    /**
     * 关联的节点
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "node_id", referencedColumnName = "node_id", insertable = false, updatable = false)
    private GradeAuditNode node;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 创建用户ID
     */
    @Column(name = "create_user_id", length = 50)
    private String createUserId;

    /**
     * 更新用户ID
     */
    @Column(name = "update_user_id", length = 50)
    private String updateUserId;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

    /**
     * 删除时间
     */
    @Column(name = "delete_time")
    private LocalDateTime deleteTime;

    /**
     * 删除用户ID
     */
    @Column(name = "delete_user_id", length = 50)
    private String deleteUserId;



}
